import { IBehaviour } from "../interface/IBehaviour";
import { EStatus } from "../common/EnumType";
import { BehaviorTree } from "../BehaviorTree";
import { BehaviorTreeConfig } from "../BehaviorTreeDefine";

export abstract class BaseBehavior<T = any> implements IBehaviour {
    protected status: EStatus = EStatus.Invalid;
    protected config: BehaviorTreeConfig = null;
    protected _target: T;

    protected _tree: BehaviorTree

    protected parent: BaseBehavior = null;//父节点，也是条件或是装饰的所属节点

    constructor(parent: BaseBehavior) {
        this.parent = parent;
        this.setStatus(EStatus.Invalid);
    }

    set tree(r: BehaviorTree) {
        this._tree = r;
    }

    get tree() {
        return this._tree;
    }



    public setConfig(config: any, target: T): void {
        this.config = config;
        this._target = target;
    }

    set target(t) {
        this._target = t;
    }

    get target() {
        return this._target;
    }

    getTarget() {
        return this.target;
    }

    public tick(dt: number = 0): EStatus {
        return this.onTick(dt);
    }

    public onTick(dt: number = 0) {
        if (this.status != EStatus.Invalid && this.status != EStatus.Running) {//已经执行过了就不再执行
            return this.status;
        }
        // if (DEBUG && this.status == EStatus.Invalid) {
        // LogUtils.log("BaseBehavior tick before", this.status, this.config);
        // }

        if (this.status == EStatus.Invalid) {
            let status = this.onTickConditions();
            if (status == EStatus.Success) {
                this.onInit();
            } else if (status == EStatus.Failure) {
                this.status = status;
                this.status = this.onTickDecorators();
                // LogUtils.log("BaseBehavior tick after ", this.status, this.config);
                return this.status;
            }
        }

        this.status = this.onUpdate(dt);

        if (this.status != EStatus.Running) {
            this.status = this.onTickDecorators();
            this.onTerminate(this.status);
        }

        // if (DEBUG && this.status != EStatus.Running) {
        //     LogUtils.log("BaseBehavior tick after ", this.status, this.config);
        // }

        return this.status;
    }

    public onInit(): void {
    }

    public onUpdate(dt: number): EStatus {
        return this.status;
    }

    public onTerminate(status: EStatus): void {
    }

    public onTickConditions(): EStatus {
        return EStatus.Success;
    }

    public onTickDecorators(): EStatus {
        return this.status;
    }

    public release(): void {
    }

    public addChild(child: IBehaviour): void {
    }

    public setStatus(status: EStatus): void {
        this.status = status;
    }

    public getStatus(): EStatus {
        return this.status;
    }

    public reset(): void {
        this.setStatus(EStatus.Invalid);
    }

    public abort(): void {
        this.onTerminate(EStatus.Aborted);
        this.setStatus(EStatus.Aborted);
    }
}